#ifndef SERIALPORTMANAGER_H
#define SERIALPORTMANAGER_H

#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QString>
#include <QList>
#include <QMap>

/**
 * @brief 串口管理器类
 * 负责扫描、打开和管理3个USB-RS485转换器
 */
class SerialPortManager : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int openedPortCount READ openedPortCount NOTIFY openedPortCountChanged)

public:
    explicit SerialPortManager(QObject *parent = nullptr);
    ~SerialPortManager();

    /**
     * @brief 扫描系统中可用的串口（QML友好）
     * @return 可用串口列表
     */
    Q_INVOKABLE QStringList scanAvailablePorts();

    /**
     * @brief 打开指定串口（QML友好）
     * @param portName 串口名称（如 "COM3"）
     * @param baudRate 波特率（默认115200）
     * @return 是否打开成功
     */
    Q_INVOKABLE bool openPort(const QString &portName, qint32 baudRate = 115200);

    /**
     * @brief 关闭指定串口（QML友好）
     * @param portName 串口名称
     */
    Q_INVOKABLE void closePort(const QString &portName);

    /**
     * @brief 关闭所有串口
     */
    void closeAllPorts();

    /**
     * @brief 获取串口对象（仅供借用，不转移所有权）
     * @param portName 串口名称
     * @return 串口对象指针，如果不存在返回nullptr
     * @note 调用者不应删除返回的指针，串口生命周期由 SerialPortManager 管理
     */
    QSerialPort *getPort(const QString &portName);

    /**
     * @brief 检查串口是否已打开（QML友好）
     * @param portName 串口名称
     * @return 是否已打开
     */
    Q_INVOKABLE bool isPortOpen(const QString &portName) const;

    /**
     * @brief 获取已打开的串口列表
     * @return 串口名称列表
     */
    QStringList getOpenedPorts() const;

    /**
     * @brief 获取已打开的串口数量
     * @return 串口数量
     */
    int openedPortCount() const { return m_ports.size(); }

signals:
    /**
     * @brief 串口打开成功信号
     * @param portName 串口名称
     */
    void portOpened(const QString &portName);

    /**
     * @brief 串口关闭信号
     * @param portName 串口名称
     */
    void portClosed(const QString &portName);

    /**
     * @brief 串口错误信号
     * @param portName 串口名称
     * @param errorString 错误信息
     */
    void portError(const QString &portName, const QString &errorString);

    /**
     * @brief 已打开串口数量改变信号
     */
    void openedPortCountChanged();

private slots:
    /**
     * @brief 串口错误处理槽函数
     * @param error 错误类型
     */
    void handleSerialError(QSerialPort::SerialPortError error);

private:
    /**
     * @brief 配置串口参数
     * @param port 串口对象
     * @param baudRate 波特率
     * @return 是否配置成功
     */
    bool configurePort(QSerialPort *port, qint32 baudRate);

private:
    QMap<QString, QSerialPort *> m_ports; ///< 串口映射表：portName -> QSerialPort*
};

#endif // SERIALPORTMANAGER_H
